#include<bits/stdc++.h>
using namespace std;
#define y1 abbbbb
using ll = long long;
const int N = 2e5 + 7;
int lowbit(int x) { return x & (-x);} 

// 矩形面积并   扫描线 + 线段树 + 离散化 
// 对 x 离散化   
// 平行于 x轴 的扫描线，则需把同一水平线上所有的操作事件完成，才能上移扫描线 

vector<int> vx;
vector<array<int, 4>> event;
int n, m;
struct info {
	int minv, mincnt; // 区间覆盖次数   区间长度 
}; 
info operator + (const info &l, const info &r) {
	info a;	
	a.minv = min(l.minv, r.minv);
	if(l.minv == r.minv)
		a.mincnt = l.mincnt + r.mincnt;
	else if(l.minv < r.minv)
		a.mincnt = l.mincnt;
	else
		a.mincnt = r.mincnt;
	return a;
}
struct node {
	int t;
	info val;
}seg[N * 8]; // 离散化要先开 2倍，一共就是8倍 

void update(int id) {
	seg[id].val = seg[id * 2].val +  seg[id * 2 + 1].val;
}
void settag(int id, int t) {
	seg[id].val.minv = seg[id].val.minv + t;
	seg[id].t = seg[id].t + t; // 增减的标记，未下传 
}
void pushdown(int id) {
	if(seg[id].t != 0) { 
		settag(id * 2, seg[id].t);
		settag(id * 2 + 1, seg[id].t); 
		seg[id].t = 0; 
	}
} 
void build(int id, int l, int r) {
	if(l == r) {
		seg[id].val = {0, vx[r] - vx[r - 1]}; 
	} else {
		int mid = (l + r) >> 1;
		build(id * 2, l, mid);
		build(id * 2 + 1, mid + 1, r);
		update(id);
	}
}
// t 覆盖次数增减 
void modify(int id, int l, int r, int ql, int qr, int t) {
	if(l == ql && r == qr) {
		settag(id, t);
		return ;
	}
	pushdown(id);  
	int mid = (l + r) >> 1;
	if(qr <= mid) 
		modify(id * 2, l, mid, ql, qr, t);
	else if(ql > mid)
		modify(id * 2 + 1, mid + 1, r, ql, qr, t);
	else { 
		modify(id * 2, l, mid, ql, mid, t);
		modify(id * 2 + 1, mid + 1, r, mid + 1, qr, t);
	}
	update(id);
}

int main() {
	scanf("%d", &n);
	for(int i = 1; i <= n; i++) {
		int x1, x2, y1, y2;
		scanf("%d%d%d%d", &x1, &x2, &y1, &y2);
		vx.push_back(x1);
		vx.push_back(x2);
		event.push_back({y1, 1, x1, x2}); // 删除 
		event.push_back({y2, -1, x1, x2}); // 添加 
	}	
	// vx离散化 
	sort(event.begin(), event.end());
	sort(vx.begin(), vx.end());
	vx.erase(unique(vx.begin(), vx.end()), vx.end());
	m = vx.size() - 1; // 片段数 
	
	// 维护 最小覆盖次数 及其 区间长度的   线段树 （一个点代表区间片段） 
	build(1, 1, m);
	int totlen = seg[1].val.mincnt; // x总长度(此时是x的最大差值) 
	int prey = 0; // 上一个y坐标（下边界） 
	ll ans = 0;
	for(auto evt : event) { // 同一y值的evt没有影响，因为y-y=0，只有y变化时才会有增加  
		int cov_x = totlen; // 假设此时x覆盖的长度是最大 
		if(seg[1].val.minv == 0) // 如果存在没有覆盖的区间 
			cov_x = totlen - seg[1].val.mincnt;
		ans += (ll)(evt[0] - prey) * cov_x; 
		prey = evt[0];
		int x1 = lower_bound(vx.begin(), vx.end(), evt[2]) - vx.begin() + 1;
		int x2 = lower_bound(vx.begin(), vx.end(), evt[3]) - vx.begin();
		if(x1 > x2) continue; // 空矩形 否则会死循环 
		// 以上操作完后，再进行信息修改 
		modify(1, 1, m, x1, x2, evt[1]);
	}
	printf("%lld\n",ans);
	
	return 0;
}
